﻿using System;
using System.Text;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml.Linq;
using PTop.Code;
using PTop.Domain.ViewModel.Wechat;
using PTop.Front.Areas.Wechat.Models;

namespace PTop.Front.Areas.Wechat.Controllers
{
    public class WechatResponseController : Controller
    {
        private readonly string _weChatToken;

        public WechatResponseController()
        {
            _weChatToken = Configs.GetValue("WeChatToken");
        }

        //
        // GET: /DealMessage/
        public ActionResult Index()
        {
            string content = string.Empty;
            string postStr = string.Empty;
            if (Request.HttpMethod.ToLower() == "post")
            {
                if (CheckSignature())
                {
                    // 解析出xml
                    postStr = PostInput();

                    // 对xml进行回复
                    if (!string.IsNullOrWhiteSpace(postStr))
                    {
                        content = ResponseMsg(postStr);
                    }
                }
            }
            else //GET 签名校验
            {
                content = Valid();
            }

            return Content(content, "text/xml", Encoding.UTF8);
        }

        /// <summary>
        /// 验证微信签名
        /// </summary>
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// <returns></returns>
        private bool CheckSignature()
        {
            string signature = Request.QueryString["signature"].ToString();
            string timestamp = Request.QueryString["timestamp"].ToString();
            string nonce = Request.QueryString["nonce"].ToString();
            string[] ArrTmp = { _weChatToken, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private string Valid()
        {
            string echoStr = Request["echoStr"];
            if (CheckSignature())
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    return echoStr;
                }
            }
            return "fail";
        }

        /// <summary>
        /// 返回信息结果(微信信息返回)
        /// </summary>
        /// <param name="weixinXML"></param>
        private string ResponseMsg(string weixinXML)
        {
            string reponseMsg = string.Empty;
            try
            {
                var doc = XElement.Parse(weixinXML);
                var msgType = doc.Element("MsgType").Value.ToLower();
                var handler = GetMsgHandler(msgType, weixinXML);
                return handler.HandleRequest();
            }
            catch (Exception ex)
            {
                //LogNet.Error("消息处理失败 xmlcontent:" + weixinXML ?? "null" + ex.Message + ex.StackTrace, ex);
                return "success";
            }
        }

        /// <summary>
        /// 获取POST返回来的数据
        /// </summary>
        /// <returns></returns>
        private string PostInput()
        {
            try
            {
                System.IO.Stream s = System.Web.HttpContext.Current.Request.InputStream;

                byte[] b = new byte[s.Length];
                s.Read(b, 0, (int)s.Length);
                string postStr = Encoding.UTF8.GetString(b);

                s.Flush();
                s.Close();
                s.Dispose();
                return postStr;
            }
            catch (Exception ex)
            {
                //LogNet.Error("解析xml错误" + ex.Message + ex.StackTrace, ex);
                throw ex;
            }
        }

        /// <summary>
        /// unix时间转换为datetime
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        private DateTime UnixTimeToTime(string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }

        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }

        private WechatMsgBase GetMsgHandler(string msgType, string xml)
        {
            WechatMsgBase handler = null;
            switch (msgType.ToLower())
            {
                case "text":
                    handler = TextMessage.LoadFromXml(xml);
                    break;
                case "event":
                    handler = EventMessage.LoadFromXml(xml);
                    break;
                case "image":
                    handler = ImgMessage.LoadFromXml(xml);
                    break;
                case "voice":
                case "video":
                case "shortvideo":
                case "location":
                case "link":
                default:
                    handler = new DefaultHandler();
                    break;
            }
            return handler;
        }

    }
}
